package com.yanqu.road.server.manager.monopolymarket;

import com.yanqu.road.entity.enums.eMonopolyMarketResType;
import com.yanqu.road.entity.monopolymarket.MonopolyMarket;
import com.yanqu.road.entity.monopolymarket.config.MonopolyMarketBackEndConfig;
import com.yanqu.road.entity.monopolymarket.config.MonopolyMarketCrossConfig;
import com.yanqu.road.entity.monopolymarket.config.MonopolyMarketResConfigData;
import com.yanqu.road.entity.monopolymarket.config.MonopolyMarketResExtendParam;
import com.yanqu.road.logic.bussiness.monopolymarket.MonopolyMarketBussiness;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.manger.MonopolyMarketCommonMgr;
import com.yanqu.road.utils.BitUtil;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.date.DateHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.List;
import java.util.Objects;

/**
 * @Description
 * @Author cwq
 * @Data 2021/9/18 19:28
 */
public class MonopolyMarketConfigMgr  extends TempMgr {

    public static Logger logger = LogManager.getLogger(MonopolyMarketConfigMgr.class.getName());

    @Override
    public boolean init() throws Exception {
        return reloadConfig();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        MonopolyMarketMgr.resConfigList = MonopolyMarketBussiness.getMonopolyMarketResConfigDataList();
        MonopolyMarketMgr.initResConfig();
        MonopolyMarketOfficeMgr.reloadConfig();
        MonopolyMarketResGrabMgr.reloadConfig();
        MonopolyMarketFortressMgr.reloadConfig();
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        checkConfigChange(true);
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }


    /**
     * 1.校验本地的配置 和后台的配置是否一致
     * 2.如果不一致 重置相对应系统 再记录修改时间
     *
     * 校验配置是否发生变化
     */
    public static boolean checkConfigChange(boolean isSyn){
        logger.info("开始检查榷场 配置是否发生变化");
        try {
            MonopolyMarketBackEndConfig config = MonopolyMarketBussiness.getMonopolyMarketBackEndConfig(ConfigHelper.getInt("channelId"));
            if(config == null){
                return false;
            }
            if(!MonopolyMarketCommonMgr.checkBackEndResConfig(config,MonopolyMarketMgr.resConfigList)){
                return false;
            }
            // 比较配置
            int bit = equalsConfig(config, MonopolyMarketMgr.crossConfig);
            if(bit == 0 ){
                return false;
            }
            int now = DateHelper.getCurrentSecond();
            MonopolyMarketCrossConfig oldCrossConfig = MonopolyMarketMgr.crossConfig;
            for(MonopolyMarket item : MonopolyMarketMgr.groupMonopolyMarketMap.values()) {
                synchronized (item) {
                    MonopolyMarketMgr.crossConfig = oldCrossConfig;
                    // 强制结算采集中的据点
                    if (BitUtil.get(bit, eMonopolyMarketResType.RES_KING.getValue() - 1)) {
                        MonopolyMarketResGrabMgr.forceSettlement(item,item.monopolyMarketResGrab.get(eMonopolyMarketResType.RES_KING.getValue()));
                    }
                    if (BitUtil.get(bit, eMonopolyMarketResType.RES_QUEEN.getValue() - 1)) {
                        MonopolyMarketResGrabMgr.forceSettlement(item,item.monopolyMarketResGrab.get(eMonopolyMarketResType.RES_QUEEN.getValue()));
                    }
                    setMonopolyMarketCrossConfig(config);
                    // 服务启动后，重新加载 检测地图是否变动
                    if(BitUtil.get(bit, eMonopolyMarketResType.OFFICE.getValue() - 1)){
                        MonopolyMarketOfficeMgr.resetOffice(item);
                        item.group.setOfficeCfgChangTime(now);
                    }
                    if(BitUtil.get(bit,eMonopolyMarketResType.RES_KING.getValue() - 1)){
                        MonopolyMarketResGrabMgr.resetResGrab(item,item.monopolyMarketResGrab.get(eMonopolyMarketResType.RES_KING.getValue()),false);
                        item.group.setKingCfgChangTime(now);
                    }
                    if(BitUtil.get(bit,eMonopolyMarketResType.RES_QUEEN.getValue() - 1)){
                        MonopolyMarketResGrabMgr.resetResGrab(item,item.monopolyMarketResGrab.get(eMonopolyMarketResType.RES_QUEEN.getValue()),false);
                        item.group.setQueenCfgChangTime(now);
                    }
                    if(isSyn){
                        for (long serverId : item.group.getServerList()){
                            MonopolyMarketCrossGroupMgr.synMonopolyMarketCrossGroup(serverId);
                        }
                        logger.info("榷场地图配置发生改变。榷场通知区服重置玩家数据。groupId:{}, serverList:{},bit:{}",item.group.getGroupId(), item.group.getServerList().toString(),bit);
                    }
                }
            }
            if (MonopolyMarketMgr.groupMonopolyMarketMap.size() == 0) {
                setMonopolyMarketCrossConfig(config);
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("检查榷场 配置异常");
            return false;
        }
        return true;
    }

    /**
     * 比较 后台配置 和跨服的配置是否一致
     * @param backEndConfig
     * @param crossConfig
     * @return 返回有变化的系统位
     */
    private static int equalsConfig(MonopolyMarketBackEndConfig backEndConfig, MonopolyMarketCrossConfig crossConfig) {
        int bit = 0;
        if (backEndConfig.getMapSize() != crossConfig.getMapSize() || backEndConfig.getMapBase() != crossConfig.getMapBase() ||
                backEndConfig.getMapAdd() != crossConfig.getMapAdd() || backEndConfig.getMapRound() != crossConfig.getMapRound() ||
                backEndConfig.getMapMidValue() != crossConfig.getMapMidValue() || !Objects.equals(backEndConfig.getBloodVolume(), crossConfig.getBloodVolume())) {
            bit = BitUtil.set(bit, eMonopolyMarketResType.RES_KING.getValue() - 1, true);
            bit = BitUtil.set(bit, eMonopolyMarketResType.RES_QUEEN.getValue() - 1, true);
        }
        for (MonopolyMarketResConfigData item : MonopolyMarketMgr.resConfigList) {
            if (item.getType() == eMonopolyMarketResType.FORTRESS.getValue()) {
                // 要塞没有扩展参数
                continue;
            }
            List<MonopolyMarketResExtendParam> backEndParamList = backEndConfig.resExtendParamMap.get(item.getId());
            List<MonopolyMarketResExtendParam> crossParamList = crossConfig.resExtendParamMap.get(item.getId());
            boolean flag = false;
            if (backEndParamList.size() != crossParamList.size()) {
                flag = true;
            } else {
                for (int i = 0; i < backEndParamList.size(); i++) {
                    MonopolyMarketResExtendParam backEndParam = backEndParamList.get(i);
                    MonopolyMarketResExtendParam crossParam = crossParamList.get(i);
                    if (backEndParam.getServerNum() != crossParam.getServerNum() || backEndParam.getCoefficient() != crossParam.getCoefficient() || backEndParam.getNum() != crossParam.getNum()) {
                        flag = true;
                        break;
                    }
                }
            }
            if (flag) {
                if (item.getType() == eMonopolyMarketResType.OFFICE.getValue()) {
                    bit = BitUtil.set(bit, 0, true);
                } else if (item.getType() == eMonopolyMarketResType.RES_KING.getValue()) {
                    bit = BitUtil.set(bit, 1, true);
                } else if (item.getType() == eMonopolyMarketResType.RES_QUEEN.getValue()) {
                    bit = BitUtil.set(bit, 2, true);
                }
            }
        }
        logger.info("后台的榷场配置.channelId:{},mapSize:{},mapBase:{},mapAdd:{},mapRound:{},mapMidValue:{},resConfig:{},bloodVolume:{}", backEndConfig.getChannelId(), backEndConfig.getMapSize(), backEndConfig.getMapBase(), backEndConfig.getMapAdd(), backEndConfig.getMapRound(), backEndConfig.getMapMidValue(), backEndConfig.getResConfig(), backEndConfig.getBloodVolume());
        logger.info("当前跨服的榷场配置.channelId:{},mapSize:{},mapBase:{},mapAdd:{},mapRound:{},mapMidValue:{},resConfig:{},bloodVolume:{}", crossConfig.getChannelId(), crossConfig.getMapSize(), crossConfig.getMapBase(), crossConfig.getMapAdd(), crossConfig.getMapRound(), crossConfig.getMapMidValue(), crossConfig.getResConfig(), crossConfig.getBloodVolume());
        logger.info("bit:{}", bit);

        return bit;
    }

    public static void setMonopolyMarketCrossConfig(MonopolyMarketBackEndConfig backEndConfig){
        MonopolyMarketCrossConfig newCrossConfig = new MonopolyMarketCrossConfig();
        newCrossConfig.setChannelId(backEndConfig.getChannelId());
        newCrossConfig.setMapSize(backEndConfig.getMapSize());
        newCrossConfig.setMapBase(backEndConfig.getMapBase());
        newCrossConfig.setMapAdd(backEndConfig.getMapAdd());
        newCrossConfig.setMapRound(backEndConfig.getMapRound());
        newCrossConfig.setMapMidValue(backEndConfig.getMapMidValue());
        newCrossConfig.setResConfig(backEndConfig.getResConfig());
        newCrossConfig.setBloodVolume(backEndConfig.getBloodVolume());
        newCrossConfig.resExtendParamMap = backEndConfig.resExtendParamMap;
        newCrossConfig.setNpcBloodConfigList(backEndConfig.getNpcBloodConfigList());

        MonopolyMarketMgr.crossConfig = newCrossConfig;
    }

}
